﻿///////////////////////////////////////////////////////////////////////////////
///
/// Cylan Client
/// Copyright (C) Shenzhen Cylan Tech. Co., Ltd. 2012
///
/// @file       StringBuffer.h
/// @brief      可增长字符串对象API
///
///////////////////////////////////////////////////////////////////////////////
#ifndef STRING_BUFFER_H
#define STRING_BUFFER_H

#include <stddef.h>

/**
 * @struct STRING_BUFFER
 * @brief  可增长字符串StringBuffer对象
 */
typedef struct STRING_BUFFER
{
    unsigned char * Data;               ///< 内存位置
    size_t          Length;             ///< 已用长度
    size_t          Size;               ///< 总长度
} STRING_BUFFER;

/**
 * @def   CStringBufferData(b)
 * @brief 获取StringBuffer包含的内容
 */
#define CStringBufferData(b)            ((b)->Data)

/**
 * @def    CStringBufferSize(b)
 * @brief  获取StringBuffer缓冲区大小
 */
#define CStringBufferSize(b)            ((b)->Size)

/**
 * @def    CStringBufferLength(b)
 * @brief  获取StringBuffer已用空间
 */
#define CStringBufferLength(b)          ((b)->Length)

/**
 * @def    CStringBufferSpace(b)
 * @brief  获取StringBuffer剩余空间
 */
#define CStringBufferSpace(b)           ((b)->Size - (b)->Length)

/**
 * @def    CStringBufferReset(b)
 * @brief  重置StringBuffer内容, 使其可以重头开始填充内容
 */
#define CStringBufferReset(b)           ((b)->Length = 0)

/**
 * @fn void CStringBufferInit(STRING_BUFFER *Buffer)
 * @brief 初始化一个StringBuffer结构
 * @param Buffer 将要初始化的StringBuffer
 */
void CStringBufferInit(STRING_BUFFER *Buffer);

/**
 * @fn void CStringBufferFree(STRING_BUFFER *Buffer)
 * @brief 释放StringBuffer
 * @param Buffer 将要释放的StringBuffer
 * @note 可以安全释放一个未使用但已初始化的StringBuffer
 */
void CStringBufferFree(STRING_BUFFER *Buffer);

/**
 * @fn int CStringBufferAppendData(STRING_BUFFER *Buffer, const void *Data, size_t Length)
 * @brief 往StringBuffer末尾添加数据
 * @param Data 添加的数据
 * @param Length 数据长度
 * @retval -1 添加失败, 内存不足
 * @retval 0 添加成功
 */
int CStringBufferAppendData(STRING_BUFFER *Buffer, const void *Data, size_t Length);

/**
 * @fn int CStringBufferAppendFormat(STRING_BUFFER *Buffer, const char *Format, ...)
 * @brief 往StringBuffer末尾添加格式化的字符串
 * @param Format 添加的格式化字符串内容
 * @param ... 格式化字符串可变参数列表
 * @retval -1 添加失败, 内存不足
 * @retval 0 添加成功
 */
int CStringBufferAppendFormat(STRING_BUFFER *Buffer, const char *Format, ...);

/**
 * @fn void CStringBufferSwap(STRING_BUFFER *Buffer1, STRING_BUFFER *Buffer2)
 * @brief 交换两个StringBuffer
 * @param Buffer1 将要交换的buffer
 * @param Buffer2 将要交换的buffer
 */
void CStringBufferSwap(STRING_BUFFER *Buffer1, STRING_BUFFER *Buffer2);


/**
 * @fn void CStringBufferReplace(STRING_BUFFER *Buffer, size_t Start, size_t Length, const void *Replace, size_t ReplaceLength)
 * @brief 替换一段Buffer
 * @param Buffer 将要替换的StringBuffer对象
 * @param Start 替换的起始位置(不可超过StringBuffer原本的长度)
 * @param Length 替换的长度(不可超过StringBuffer原本的长度)
 * @param Replace 替换成的内容
 * @param ReplaceLength 替换成的长度
 * @retval -1 替换失败
 * @retval 0 替换成功
 */
int CStringBufferReplace(STRING_BUFFER *Buffer, size_t Start, size_t Length, const void *Replace, size_t ReplaceLength);

/**
 * @fn int CStringBufferExpand(STRING_BUFFER *Buffer, size_t NewSize)
 * @brief 扩大一个StringBuffer的内存空间
 * @param Buffer 将要初始化的StringBuffer
 * @param NewSize 指定的新内存大小
 * @retval 执行后StringBuffer的内存大小
 * @note 如果新的内存大小比原本还要小将不执行任何操作
 */
int CStringBufferExpand(STRING_BUFFER *Buffer, size_t NewSize);

#endif /* STRING_BUFFER_H */
